import { _decorator, JsonAsset, resources } from 'cc';
import BaseManager from '../../../../extensions/app/assets/base/BaseManager';
import { app } from 'db://assets/app/app';
import { IPartData } from '../../app-model/ConfigInterface';
import { PartData } from '../../app-model/TablesClass';
const { ccclass, property } = _decorator;
@ccclass('TablesManager')
export class TablesManager extends BaseManager {

    /**
     * 配置表
     */
    private _TablesMap: Map<string, any> = new Map()


    // [无序] 加载完成时触发
    protected onLoad() { }

    // [无序] 自身初始化完成, init执行完毕后被调用
    protected onInited() { }

    // [无序] 所有manager初始化完成
    protected onFinished() { }

    // [无序] 初始化manager，在初始化完成后，调用finish方法
    protected init(finish: Function) {
        super.init(finish);
    }

    /**
     * 异步加载配置表
     * @param path 配置表路径（惰性加载）
     */
    public async LoadTable<T>(path: string): Promise<T> {
        //检查缓存
        if (this._TablesMap.has(path)) {
            return this._TablesMap.get(path);
        }

        try {
            //异步加载
            const jsonAsset = await app.manager.loader.loadAsync({
                path: `config/${path}`,
                bundle: "res-native",
                type: JsonAsset
            });
            const table = jsonAsset.json as T;

            //存入缓存
            this._TablesMap.set(path, table);
            app.lib.logger.success(`加载配置表成功：${path}`)
            return table;
        } catch (error) {
            app.lib.logger.error(`配置表错误：${path}`, error)
            throw error;
        }
    }

    public GetTable<T>(path: string): T | null {
        if (this._TablesMap.has(path)) {
            return this._TablesMap.get(path) as T;
        }

        app.lib.logger.warn(`配置表未加载：${path}`);
        return null;
    }

    /**
     * 释放配置表资源
     * @param path 配置表路径
     */
    public ReleaseTable(path: string): void {
        if (this._TablesMap.has(path)) {
            app.manager.loader.release({
                path: `config/${path}`,
                bundle: "res-native",
                type: JsonAsset
            })
        }
    }


    //#region  配置数据写在这

    private _PartDatas: Map<number, Map<number, IPartData>> = new Map();

    /**
     * 获取配置数据
     * @returns 
     */
    public async GetPartDatas(): Promise<Map<number, Map<number, IPartData>>> {
        if (this._PartDatas.size == 0) {
            const _ = await this._initPartData();
        }
        return this._PartDatas;
    }

    /**
     * 获取配置数据
     * @param part_type 部位类型
     * @param bid 数据ID
     */
    public async GetPartData(part_type: number, bid: number): Promise<IPartData | null> {
        if (this._PartDatas.size == 0) {
            const _ = await this._initPartData();
        }

        if (this._PartDatas.size == 0) {
            app.lib.logger.warn(`获取配置数据:${PartData.name}失败,part_type:${part_type},id:${bid}`)
            return null;
        }

        const maps = this._PartDatas.get(part_type)
        if (!maps) {
            app.lib.logger.warn(`获取配置数据:${PartData.name}失败,part_type:${part_type},id:${bid}`)
            return null;
        }

        const map = maps.get(bid);
        if (!map) {
            app.lib.logger.warn(`获取配置数据:${PartData.name}失败,part_type:${part_type},id:${bid}`)
            return null;
        }

        return map;
    }

    /**
     * 初始化PartData数据
     */
    private async _initPartData(): Promise<void> {
        let datas = await PartData.data;

        if (datas == null)
            return;

        // 使用 for...in 遍历对象的键
        for (const key in datas) {
            if (datas.hasOwnProperty(key)) { // 确保该键是对象自身的属性，而不是继承的属性
                const item = datas[key];
                const part_type = item.part_type;
                const bid = item.bid;

                if (!this._PartDatas.has(part_type)) {
                    this._PartDatas.set(part_type, new Map<number, IPartData>())
                }

                const map = this._PartDatas.get(part_type)
                map.set(bid, item);
                this._PartDatas.set(part_type, map);
            }
        }
    }

    //#endregion
}


type Constructor<T = {}> = new (...args: any[]) => T;

/**
 * 自动加载装饰器（高级用法）
 * @param path 
 * @returns 
 */
export function AutoTableLoad<T>(path: string) {
    app.lib.logger.log(`[AutoTableLoad] 开始加载配置 step 1: ${path}`);
    return <U extends Constructor>(target: U) => {
        app.lib.logger.log(`[AutoTableLoad] 开始加载配置 step 2: ${path}`);
        return class extends target {
            private static _loadPromise: Promise<T> | null = null;

            // ✅ 正确的懒加载访问器
            static get data(): Promise<T> {
                if (!this._loadPromise) {
                    this._loadPromise = (async () => {
                        app.lib.logger.log(`[AutoTableLoad] 开始加载配置 step 3: ${path}`);
                        return await app.manager.tables.LoadTable(path);
                    })();
                }
                return this._loadPromise;
            }
        } as unknown as U & { data: Promise<T> };
    }
}